#include "LCD_Driver.h"
// extern FSMC LCD;//触摸屏对象
extern USART cout;
void LCD_Delay_ms(uint8_t Num)
{
	uint16_t Timer;
	while(Num--)
	{
		Timer = 11500;
		while(Timer--);
	}
}
void LCD_Reset(void)
{
	_LCD->Command = 0x01;
	LCD_Delay_ms(1000);
	// LCD_RST = 0;
	// LCD_Delay_ms(150);
	// LCD_RST = 1;
	// LCD_Delay_ms(50);
}
void LCD_Interface_Init()
{
	GPIO::InitTypeDef aaa;
	aaa.Speed = Speed_50MHz;
	aaa.Mode = Mode_AF_PP;

	//NE4    A10
	aaa.Pin = Pin_12 | Pin_0;
	PG.Init(aaa);

	//NWE   NOE   D0     D1     D2    D3    D13   D14   D15
	aaa.Pin = Pin_5 | Pin_4 | Pin_14 | Pin_15 | Pin_0 | Pin_1 | Pin_8 | Pin_9 | Pin_10;
	PD.Init(aaa);

	//D4    D5    D6    D7     D8     D9     D10    D11    D12
	aaa.Pin = Pin_7 | Pin_8 | Pin_9 | Pin_10 | Pin_11 | Pin_12 | Pin_13 | Pin_14 | Pin_15;
	PE.Init(aaa);

	aaa.Mode = Mode_Out_PP;
	aaa.Pin = Pin_5;
	PC.Init(aaa);

	aaa.Pin = Pin_0;
	PB.Init(aaa);

	FSMC::NORSRAMInitTypeDef bbb;
	FSMC::NORSRAMTimingInitTypeDef readWriteTiming, writeTiming;

	readWriteTiming.FSMC_AddressSetupTime = 0x01;	 //µØÖ·½¨Á¢Ê±¼ä£¨ADDSET£©Îª2¸öHCLK 1/36M=27ns
	readWriteTiming.FSMC_AddressHoldTime = 0x00;	 //µØÖ·±£³ÖÊ±¼ä£¨ADDHLD£©Ä£Ê½AÎ´ÓÃµ½
	readWriteTiming.FSMC_DataSetupTime = 0x0F;		 // Êý¾Ý±£´æÊ±¼äÎª16¸öHCLK,ÒòÎªÒº¾§Çý¶¯ICµÄ¶ÁÊý¾ÝµÄÊ±ºò£¬ËÙ¶È²»ÄÜÌ«¿ì£¬ÓÈÆä¶Ô1289Õâ¸öIC¡£
	readWriteTiming.FSMC_BusTurnAroundDuration = 0x00;
	readWriteTiming.FSMC_CLKDivision = 0x00;
	readWriteTiming.FSMC_DataLatency = 0x00;
	readWriteTiming.FSMC_AccessMode = FSMC_AccessMode_A;	 //Ä£Ê½A


	writeTiming.FSMC_AddressSetupTime = 0x02;	 //0x01 µØÖ·½¨Á¢Ê±¼ä£¨ADDSET£©Îª1¸öHCLK
	writeTiming.FSMC_AddressHoldTime = 0x00;	 //µØÖ·±£³ÖÊ±¼ä£¨A
	writeTiming.FSMC_DataSetupTime = 0x05;		 ////0x03 Êý¾Ý±£´æÊ±¼äÎª4¸öHCLK
	writeTiming.FSMC_BusTurnAroundDuration = 0x00;
	writeTiming.FSMC_CLKDivision = 0x00;
	writeTiming.FSMC_DataLatency = 0x00;
	writeTiming.FSMC_AccessMode = FSMC_AccessMode_A;	 //Ä£Ê½A


	bbb.FSMC_Bank = FSMC_Bank1_NORSRAM4;//  ÕâÀïÎÒÃÇÊ¹ÓÃNE4 £¬Ò²¾Í¶ÔÓ¦BTCR[6],[7]¡£
	bbb.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; // ²»¸´ÓÃÊý¾ÝµØÖ·
	bbb.FSMC_MemoryType = FSMC_MemoryType_SRAM; // FSMC_MemoryType_SRAM;  //SRAM
	bbb.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;//´æ´¢Æ÷Êý¾Ý¿í¶ÈÎª16bit
	bbb.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; // FSMC_BurstAccessMode_Disable;
	bbb.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
	bbb.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
	bbb.FSMC_WrapMode = FSMC_WrapMode_Disable;
	bbb.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
	bbb.FSMC_WriteOperation = FSMC_WriteOperation_Enable;	//  ´æ´¢Æ÷Ð´Ê¹ÄÜ
	bbb.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
	bbb.FSMC_ExtendedMode = FSMC_ExtendedMode_Enable; // ¶ÁÐ´Ê¹ÓÃ²»Í¬µÄÊ±Ðò
	bbb.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
	bbb.FSMC_ReadWriteTimingStruct = &readWriteTiming; //¶ÁÐ´Ê±Ðò
	bbb.FSMC_WriteTimingStruct = &writeTiming;  //Ð´Ê±Ðò

//	bbb.FSMC_Bank = FSMC_Bank1_NORSRAM4;
//	bbb.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
//	bbb.FSMC_MemoryType = FSMC_MemoryType_SRAM;
//	bbb.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
//	bbb.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
//	bbb.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
//	bbb.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
//	bbb.FSMC_WrapMode = FSMC_WrapMode_Disable;
//	bbb.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
//	bbb.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
//	bbb.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
//	bbb.FSMC_ExtendedMode = FSMC_ExtendedMode_Enable;
//	bbb.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
//	bbb.FSMC_ReadWriteTimingStruct = &readWriteTiming;
//	bbb.FSMC_WriteTimingStruct = &writeTiming;
	FSMC LCD(FSMC_Bank1_NORSRAM4);//触摸屏对象
	LCD.NORSRAMInit(bbb);
	LCD.NORSRAMCmd(ENABLE);
}

uint32_t getId()
{
	_LCD->Command = 0xD3;
	uint32_t id = 0;
	for(auto i=0;i<4;i++)
	{
		id <<= 8;
		id |= _LCD->Data;
	}
	return id;
}
void LCDx_Init()
{
	LCD_Interface_Init();
	LCD_Reset();
	
	cout.Printf("LCD Id:%#X\r\n", getId());
	LCD_Write_Command(0xCF);
	LCD_Write_Data(0x00);
	LCD_Write_Data(0xC1);
	LCD_Write_Data(0X30);
	LCD_Write_Command(0xED);
	LCD_Write_Data(0x64);
	LCD_Write_Data(0x03);
	LCD_Write_Data(0X12);
	LCD_Write_Data(0X81);
	LCD_Write_Command(0xE8);
	LCD_Write_Data(0x85);
	LCD_Write_Data(0x10);
	LCD_Write_Data(0x7A);
	LCD_Write_Command(0xCB);
	LCD_Write_Data(0x39);
	LCD_Write_Data(0x2C);
	LCD_Write_Data(0x00);
	LCD_Write_Data(0x34);
	LCD_Write_Data(0x02);
	LCD_Write_Command(0xF7);
	LCD_Write_Data(0x20);
	LCD_Write_Command(0xEA);
	LCD_Write_Data(0x00);
	LCD_Write_Data(0x00);
	LCD_Write_Command(0xC0);//Power control
	LCD_Write_Data(0x1B);//VRH[5:0]
	LCD_Write_Command(0xC1);//Power control
	LCD_Write_Data(0x01);//SAP[2:0];BT[3:0]
	LCD_Write_Command(0xC5);//VCM control
	LCD_Write_Data(0x30);//3F
	LCD_Write_Data(0x30);//3C
	LCD_Write_Command(0xC7);//VCM control2
	LCD_Write_Data(0XB7);
	LCD_Write_Command(0x36);// Memory Access Control
	LCD_Write_Data(0x48);
	LCD_Write_Command(0x3A);
	LCD_Write_Data(0x55);
	LCD_Write_Command(0xB1);
	LCD_Write_Data(0x00);
	LCD_Write_Data(0x1A);
	LCD_Write_Command(0xB6);// Display Function Control
	LCD_Write_Data(0x0A);
	LCD_Write_Data(0xA2);
	LCD_Write_Command(0xF2);// 3Gamma Function Disable
	LCD_Write_Data(0x00);
	LCD_Write_Command(0x26);//Gamma curve selected
	LCD_Write_Data(0x01);
	LCD_Write_Command(0xE0);//Set Gamma
	LCD_Write_Data(0x0F);
	LCD_Write_Data(0x2A);
	LCD_Write_Data(0x28);
	LCD_Write_Data(0x08);
	LCD_Write_Data(0x0E);
	LCD_Write_Data(0x08);
	LCD_Write_Data(0x54);
	LCD_Write_Data(0XA9);
	LCD_Write_Data(0x43);
	LCD_Write_Data(0x0A);
	LCD_Write_Data(0x0F);
	LCD_Write_Data(0x00);
	LCD_Write_Data(0x00);
	LCD_Write_Data(0x00);
	LCD_Write_Data(0x00);
	LCD_Write_Command(0XE1);//Set Gamma
	LCD_Write_Data(0x00);
	LCD_Write_Data(0x15);
	LCD_Write_Data(0x17);
	LCD_Write_Data(0x07);
	LCD_Write_Data(0x11);
	LCD_Write_Data(0x06);
	LCD_Write_Data(0x2B);
	LCD_Write_Data(0x56);
	LCD_Write_Data(0x3C);
	LCD_Write_Data(0x05);
	LCD_Write_Data(0x10);
	LCD_Write_Data(0x0F);
	LCD_Write_Data(0x3F);
	LCD_Write_Data(0x3F);
	LCD_Write_Data(0x0F);
	LCD_Write_Command(0x2B);
	LCD_Write_Data(0x00);
	LCD_Write_Data(0x00);
	LCD_Write_Data(0x01);
	LCD_Write_Data(0x3f);
	LCD_Write_Command(0x2A);
	LCD_Write_Data(0x00);
	LCD_Write_Data(0x00);
	LCD_Write_Data(0x00);
	LCD_Write_Data(0xEF);
	LCD_Write_Command(0x11);//Exit Sleep
	// LCD_Delay_ms(200);
	
	LCD_Write_Command(0x29);//display on
	// LCD_Delay_ms(150);

	LCD_Write_Command(0x36);
	LCD_Write_Data(0x49);//49左横屏 89右横屏
	LCD_BL = 1;
}
void LCD_OpenWin(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
{
	LCD_Write_Command(0x2A);
	LCD_Write_Data(y0 >> 8);
	LCD_Write_Data(0x00FF & y0);
	LCD_Write_Data(y1 >> 8);
	LCD_Write_Data(0x00FF & y1);
	LCD_Write_Command(0x2B);
	LCD_Write_Data(x0 >> 8);
	LCD_Write_Data(0x00FF & x0);
	LCD_Write_Data(x1 >> 8);
	LCD_Write_Data(0x00FF & x1);
	LCD_Write_Command(0x2C);
}
void LCD_Fill(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t Color)
{
	uint16_t i, j;
	LCD_OpenWin(x0, y0, x1, y1);
	for(i = x0; i <= x1; i++)
		for(j = y0; j <= y1; j++)
			LCD_Write_Data(Color);
}
void LCD_DrawPoint(uint16_t x1, uint16_t y1, uint16_t Color)
{
	LCD_OpenWin(x1, y1, x1, y1);
	LCD_Write_Data(Color);
}

